/**
 * 增强路径匹配功能测试套件
 * 用于验证路径匹配、参数提取、优先级排序等功能
 */

// 测试用的API映射配置
const TEST_API_MAPPING = {
  // 精确匹配（最高优先级）
  'GET /api/v1/user/profile': { controller: 'user', method: 'getCurrentProfile' },
  'GET /api/v1/habits/trending': { controller: 'habits', method: 'getTrending' },
  
  // 参数化匹配
  'GET /api/v1/users/:id': { controller: 'user', method: 'getUserDetail' },
  'PUT /api/v1/users/:id': { controller: 'user', method: 'updateUser' },
  'DELETE /api/v1/users/:id': { controller: 'user', method: 'deleteUser' },
  
  // 嵌套资源
  'GET /api/v1/users/:userId/habits': { controller: 'habits', method: 'getUserHabits' },
  'GET /api/v1/users/:userId/habits/:habitId': { controller: 'habits', method: 'getUserHabitDetail' },
  'POST /api/v1/users/:userId/habits/:habitId/complete': { controller: 'habits', method: 'markComplete' },
  
  // 参数类型验证
  'GET /api/v1/habits/:id(\\d+)': { controller: 'habits', method: 'getHabitDetail' },
  'GET /api/v1/files/:filename([\\w\\-\\.]+)': { controller: 'upload', method: 'getFile' },
  
  // 单级通配符
  'GET /api/v1/files/*/download': { controller: 'upload', method: 'downloadFile' },
  'GET /api/v1/search/*': { controller: 'search', method: 'globalSearch' },
  'DELETE /api/v1/cache/*/clear': { controller: 'cache', method: 'clearCache' },
  
  // 多级通配符
  'GET /api/v1/admin/**/logs': { controller: 'admin', method: 'getLogs' },
  'DELETE /api/v1/cache/**/clear': { controller: 'cache', method: 'clearDeepCache' },
  'GET /api/v1/reports/**/export': { controller: 'reports', method: 'exportReport' },
  
  // 版本化API
  'GET /api/v:version/habits': { controller: 'habits', method: 'getHabits' },
  'GET /api/v:version/users/:id': { controller: 'user', method: 'getVersionedUser' },
  
  // 通用资源操作
  'GET /api/v1/:resource': { controller: 'generic', method: 'getResourceList' },
  'GET /api/v1/:resource/:id': { controller: 'generic', method: 'getResourceDetail' },
  'POST /api/v1/:resource': { controller: 'generic', method: 'createResource' },
  'PUT /api/v1/:resource/:id': { controller: 'generic', method: 'updateResource' },
  'DELETE /api/v1/:resource/:id': { controller: 'generic', method: 'deleteResource' }
}

/**
 * 测试用例定义
 */
const TEST_CASES = [
  // 精确匹配测试
  {
    name: '精确匹配 - 用户资料',
    path: '/api/v1/user/profile',
    method: 'GET',
    expected: {
      controller: 'user',
      method: 'getCurrentProfile',
      pathParams: {},
      priority: 'exact'
    }
  },
  {
    name: '精确匹配 - 热门习惯',
    path: '/api/v1/habits/trending',
    method: 'GET',
    expected: {
      controller: 'habits',
      method: 'getTrending',
      pathParams: {},
      priority: 'exact'
    }
  },
  
  // 参数化匹配测试
  {
    name: '单参数匹配 - 用户详情',
    path: '/api/v1/users/123',
    method: 'GET',
    expected: {
      controller: 'user',
      method: 'getUserDetail',
      pathParams: { id: '123' },
      priority: 'parameterized'
    }
  },
  {
    name: '单参数匹配 - 更新用户',
    path: '/api/v1/users/456',
    method: 'PUT',
    expected: {
      controller: 'user',
      method: 'updateUser',
      pathParams: { id: '456' },
      priority: 'parameterized'
    }
  },
  
  // 嵌套资源测试
  {
    name: '嵌套资源 - 用户习惯列表',
    path: '/api/v1/users/123/habits',
    method: 'GET',
    expected: {
      controller: 'habits',
      method: 'getUserHabits',
      pathParams: { userId: '123' },
      priority: 'parameterized'
    }
  },
  {
    name: '嵌套资源 - 用户习惯详情',
    path: '/api/v1/users/123/habits/456',
    method: 'GET',
    expected: {
      controller: 'habits',
      method: 'getUserHabitDetail',
      pathParams: { userId: '123', habitId: '456' },
      priority: 'parameterized'
    }
  },
  {
    name: '嵌套资源 - 完成习惯',
    path: '/api/v1/users/123/habits/456/complete',
    method: 'POST',
    expected: {
      controller: 'habits',
      method: 'markComplete',
      pathParams: { userId: '123', habitId: '456' },
      priority: 'parameterized'
    }
  },
  
  // 参数类型验证测试
  {
    name: '参数类型验证 - 数字ID',
    path: '/api/v1/habits/789',
    method: 'GET',
    expected: {
      controller: 'habits',
      method: 'getHabitDetail',
      pathParams: { id: '789' },
      priority: 'parameterized'
    }
  },
  {
    name: '参数类型验证 - 文件名',
    path: '/api/v1/files/document.pdf',
    method: 'GET',
    expected: {
      controller: 'upload',
      method: 'getFile',
      pathParams: { filename: 'document.pdf' },
      priority: 'parameterized'
    }
  },
  
  // 单级通配符测试
  {
    name: '单级通配符 - 文件下载',
    path: '/api/v1/files/image.jpg/download',
    method: 'GET',
    expected: {
      controller: 'upload',
      method: 'downloadFile',
      pathParams: {},
      priority: 'wildcard'
    }
  },
  {
    name: '单级通配符 - 全局搜索',
    path: '/api/v1/search/habits',
    method: 'GET',
    expected: {
      controller: 'search',
      method: 'globalSearch',
      pathParams: {},
      priority: 'wildcard'
    }
  },
  {
    name: '单级通配符 - 缓存清理',
    path: '/api/v1/cache/user/clear',
    method: 'DELETE',
    expected: {
      controller: 'cache',
      method: 'clearCache',
      pathParams: {},
      priority: 'wildcard'
    }
  },
  
  // 多级通配符测试
  {
    name: '多级通配符 - 管理员日志',
    path: '/api/v1/admin/system/error/logs',
    method: 'GET',
    expected: {
      controller: 'admin',
      method: 'getLogs',
      pathParams: {},
      priority: 'wildcard'
    }
  },
  {
    name: '多级通配符 - 深度缓存清理',
    path: '/api/v1/cache/user/123/session/clear',
    method: 'DELETE',
    expected: {
      controller: 'cache',
      method: 'clearDeepCache',
      pathParams: {},
      priority: 'wildcard'
    }
  },
  {
    name: '多级通配符 - 报告导出',
    path: '/api/v1/reports/monthly/2024/01/export',
    method: 'GET',
    expected: {
      controller: 'reports',
      method: 'exportReport',
      pathParams: {},
      priority: 'wildcard'
    }
  },
  
  // 版本化API测试
  {
    name: '版本化API - 习惯列表',
    path: '/api/v1/habits',
    method: 'GET',
    expected: {
      controller: 'habits',
      method: 'getHabits',
      pathParams: { version: '1' },
      priority: 'parameterized'
    }
  },
  {
    name: '版本化API - 用户详情',
    path: '/api/v2/users/123',
    method: 'GET',
    expected: {
      controller: 'user',
      method: 'getVersionedUser',
      pathParams: { version: '2', id: '123' },
      priority: 'parameterized'
    }
  },
  
  // 通用资源操作测试
  {
    name: '通用资源 - 资源列表',
    path: '/api/v1/categories',
    method: 'GET',
    expected: {
      controller: 'generic',
      method: 'getResourceList',
      pathParams: { resource: 'categories' },
      priority: 'parameterized'
    }
  },
  {
    name: '通用资源 - 资源详情',
    path: '/api/v1/tags/123',
    method: 'GET',
    expected: {
      controller: 'generic',
      method: 'getResourceDetail',
      pathParams: { resource: 'tags', id: '123' },
      priority: 'parameterized'
    }
  },
  {
    name: '通用资源 - 创建资源',
    path: '/api/v1/comments',
    method: 'POST',
    expected: {
      controller: 'generic',
      method: 'createResource',
      pathParams: { resource: 'comments' },
      priority: 'parameterized'
    }
  },
  
  // 查询参数测试
  {
    name: '查询参数 - 分页查询',
    path: '/api/v1/habits?page=1&size=20&status=active',
    method: 'GET',
    expected: {
      controller: 'habits',
      method: 'getHabits',
      pathParams: { version: '1' },
      queryParams: { page: '1', size: '20', status: 'active' },
      priority: 'parameterized'
    }
  },
  
  // 优先级测试
  {
    name: '优先级测试 - 精确匹配优于参数匹配',
    path: '/api/v1/habits/trending',
    method: 'GET',
    expected: {
      controller: 'habits',
      method: 'getTrending', // 应该匹配精确路径，而不是 :id 参数路径
      pathParams: {},
      priority: 'exact'
    }
  }
]

/**
 * 失败测试用例
 */
const FAILURE_TEST_CASES = [
  {
    name: '路径未匹配',
    path: '/api/v1/unknown/endpoint',
    method: 'GET',
    expectedError: 'API路径未找到'
  },
  {
    name: '参数类型验证失败 - 非数字ID',
    path: '/api/v1/habits/abc',
    method: 'GET',
    expectedError: null // 应该匹配通用资源路径
  },
  {
    name: '方法不匹配',
    path: '/api/v1/user/profile',
    method: 'POST',
    expectedError: 'API路径未找到'
  }
]

/**
 * 性能测试用例
 */
const PERFORMANCE_TEST_CASES = [
  { path: '/api/v1/user/profile', method: 'GET' },
  { path: '/api/v1/users/123', method: 'GET' },
  { path: '/api/v1/users/123/habits/456', method: 'GET' },
  { path: '/api/v1/files/document.pdf/download', method: 'GET' },
  { path: '/api/v1/admin/system/logs', method: 'GET' },
  { path: '/api/v1/categories', method: 'GET' },
  { path: '/api/v1/tags/123', method: 'GET' }
]

/**
 * 运行单个测试用例
 */
function runTestCase(testCase, requestManager) {
  try {
    const result = requestManager.findApiHandler(testCase.path, testCase.method)
    
    if (!result) {
      return {
        name: testCase.name,
        passed: false,
        error: '未找到匹配的API处理器',
        expected: testCase.expected,
        actual: null
      }
    }
    
    const { handler, pathParams, queryParams } = result
    
    // 验证控制器和方法
    const controllerMatch = handler.controller === testCase.expected.controller
    const methodMatch = handler.method === testCase.expected.method
    
    // 验证路径参数
    const pathParamsMatch = JSON.stringify(pathParams) === JSON.stringify(testCase.expected.pathParams)
    
    // 验证查询参数（如果有）
    let queryParamsMatch = true
    if (testCase.expected.queryParams) {
      queryParamsMatch = JSON.stringify(queryParams) === JSON.stringify(testCase.expected.queryParams)
    }
    
    const passed = controllerMatch && methodMatch && pathParamsMatch && queryParamsMatch
    
    return {
      name: testCase.name,
      passed,
      error: passed ? null : '结果不匹配',
      expected: testCase.expected,
      actual: {
        controller: handler.controller,
        method: handler.method,
        pathParams,
        queryParams
      }
    }
  } catch (error) {
    return {
      name: testCase.name,
      passed: false,
      error: error.message,
      expected: testCase.expected,
      actual: null
    }
  }
}

/**
 * 运行失败测试用例
 */
function runFailureTestCase(testCase, requestManager) {
  try {
    const result = requestManager.findApiHandler(testCase.path, testCase.method)
    
    if (testCase.expectedError && !result) {
      return {
        name: testCase.name,
        passed: true,
        error: null
      }
    }
    
    if (!testCase.expectedError && result) {
      return {
        name: testCase.name,
        passed: true,
        error: null,
        actual: result
      }
    }
    
    return {
      name: testCase.name,
      passed: false,
      error: `期望${testCase.expectedError ? '失败' : '成功'}，但实际${result ? '成功' : '失败'}`,
      expected: testCase.expectedError,
      actual: result
    }
  } catch (error) {
    const passed = testCase.expectedError && error.message.includes(testCase.expectedError)
    return {
      name: testCase.name,
      passed,
      error: passed ? null : `期望错误包含 "${testCase.expectedError}"，实际错误: ${error.message}`,
      expected: testCase.expectedError,
      actual: error.message
    }
  }
}

/**
 * 性能测试
 */
function runPerformanceTest(requestManager, iterations = 1000) {
  const startTime = Date.now()
  
  for (let i = 0; i < iterations; i++) {
    for (const testCase of PERFORMANCE_TEST_CASES) {
      requestManager.findApiHandler(testCase.path, testCase.method)
    }
  }
  
  const endTime = Date.now()
  const totalTime = endTime - startTime
  const avgTime = totalTime / (iterations * PERFORMANCE_TEST_CASES.length)
  
  return {
    totalTime,
    avgTime,
    iterations,
    testCases: PERFORMANCE_TEST_CASES.length,
    totalRequests: iterations * PERFORMANCE_TEST_CASES.length
  }
}

/**
 * 运行完整测试套件
 */
export function runPathMatchingTests(requestManager) {
  console.log('🧪 开始运行增强路径匹配测试套件...')
  
  // 临时设置测试API映射
  const originalMapping = requestManager.API_MAPPING
  requestManager.API_MAPPING = TEST_API_MAPPING
  
  try {
    const results = {
      success: [],
      failure: [],
      performance: null
    }
    
    // 运行成功测试用例
    console.log('\n📋 运行功能测试用例...')
    for (const testCase of TEST_CASES) {
      const result = runTestCase(testCase, requestManager)
      if (result.passed) {
        results.success.push(result)
        console.log(`✅ ${result.name}`)
      } else {
        results.failure.push(result)
        console.log(`❌ ${result.name}: ${result.error}`)
        console.log(`   期望:`, result.expected)
        console.log(`   实际:`, result.actual)
      }
    }
    
    // 运行失败测试用例
    console.log('\n🚫 运行失败测试用例...')
    for (const testCase of FAILURE_TEST_CASES) {
      const result = runFailureTestCase(testCase, requestManager)
      if (result.passed) {
        results.success.push(result)
        console.log(`✅ ${result.name}`)
      } else {
        results.failure.push(result)
        console.log(`❌ ${result.name}: ${result.error}`)
      }
    }
    
    // 运行性能测试
    console.log('\n⚡ 运行性能测试...')
    results.performance = runPerformanceTest(requestManager)
    console.log(`性能测试结果:`)
    console.log(`  总时间: ${results.performance.totalTime}ms`)
    console.log(`  平均时间: ${results.performance.avgTime.toFixed(3)}ms/请求`)
    console.log(`  总请求数: ${results.performance.totalRequests}`)
    
    // 输出测试总结
    console.log('\n📊 测试总结:')
    console.log(`✅ 成功: ${results.success.length}`)
    console.log(`❌ 失败: ${results.failure.length}`)
    console.log(`📈 成功率: ${((results.success.length / (results.success.length + results.failure.length)) * 100).toFixed(1)}%`)
    
    return results
  } finally {
    // 恢复原始API映射
    requestManager.API_MAPPING = originalMapping
  }
}

/**
 * 快速验证特定路径
 */
export function testSpecificPath(requestManager, path, method = 'GET') {
  console.log(`🔍 测试路径: ${method} ${path}`)
  
  try {
    const result = requestManager.findApiHandler(path, method)
    
    if (result) {
      console.log('✅ 匹配成功:')
      console.log(`  控制器: ${result.handler.controller}`)
      console.log(`  方法: ${result.handler.method}`)
      console.log(`  路径参数:`, result.pathParams)
      console.log(`  查询参数:`, result.queryParams)
      console.log(`  完整参数:`, result.fullParams)
    } else {
      console.log('❌ 未找到匹配的API处理器')
    }
    
    return result
  } catch (error) {
    console.log(`❌ 测试失败: ${error.message}`)
    return null
  }
}

/**
 * 批量测试路径列表
 */
export function testPathList(requestManager, pathList) {
  console.log(`🔍 批量测试 ${pathList.length} 个路径...`)
  
  const results = []
  
  for (const { path, method = 'GET' } of pathList) {
    const result = testSpecificPath(requestManager, path, method)
    results.push({ path, method, result })
  }
  
  return results
}

export default {
  runPathMatchingTests,
  testSpecificPath,
  testPathList,
  TEST_CASES,
  FAILURE_TEST_CASES,
  PERFORMANCE_TEST_CASES
}